﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Circle.Domain.Interface.Service;
using Circle.Domain.Entity;
using Circle.Domain.Interface.UnitOfWork;
using Circle.Web.ViewModelsClient;
using Circle.Web.ViewModels;
using System.Web.Mvc;
using Circle.Manager;
using Circle.Domain.Model;
using Circle.Web.Drivers.Contract;

namespace Circle.Web.Drivers
{

    public abstract class ConvertableDriver<VM, CM> : BaseDriver, IConvertableDriver<VM,CM>
        where VM : ViewModel, new()
        where CM : ClientModel, new()
    {

        public abstract VM Create(string[] includeProperties = null);

        public virtual CM CreateClient(string[] includeProperties = null)
        {
            return new CM();
        }

        public abstract VM FromClient(VM m, CM cModel, string[] includeProperties = null);

        public virtual CM ToClient(VM m, CM cModel = null, string[] includeProperties = null, bool serverStatus = true)
        {
            if (cModel == null) return new CM();
            return cModel;
        }

        protected virtual ModelListClient<CM> ToClientCollection(ICollection<VM> collection)
        {
            if (collection == null) return null;
            ModelListClient<CM> list = new ModelListClient<CM>();
            foreach (VM m in collection)
            {
                list.Add(ToClient(m));
            }
            return list;
        }
    }

    public abstract class ConvertableEntityDriver<E, CM> : EntityDriver, IEntityConvertableDriver<E, CM>
        where E : BaseEntity
        where CM : IdenticalClientModel, new()
    {
        protected IBaseCrudService<E> CrudService;

        public ConvertableEntityDriver(IBaseCrudService<E> service)
        {
            CrudService = service;
        }

        public virtual E Create(string[] includeProperties = null)
        {
            return CrudService.Create();
        }

        public virtual E Get(Guid id, string[] includeProperties = null)
        {
            return CrudService.Get(id, includeProperties);
        }

        public virtual CM CreateClient(string[] includeProperties = null)
        {
            return new CM();
        }

        public abstract E FromClient(E m, CM cModel, string[] includeProperties = null);

        public virtual CM ToClient(E m, CM cModel = null, string[] excludeProperties = null, bool serverStatus = true)
        {
            if (cModel == null) { 
                cModel = new CM();
                cModel.Id = m.Id;
            }
            cModel.ServerStatus = serverStatus;

            return cModel;
        }

        protected virtual IList<CM> ToClientCollection(IList<E> collection)
        {
            if (collection == null) return null;
            List<CM> list = new List<CM>();
            foreach (E entity in collection)
            {
                list.Add(ToClient(entity));
            }
            return list;
        }
    }
}